package io.github.wslxm.springbootplus2.utils;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * Oauth2 调用当前系统的加签接口的加签工具类
 *
 * @author wangsong
 * @date 2023/10/08
 */
public class XjOauth2Util {

    private static String appKey = "xijia";
    private static String secretKey = "xijia@qwer";

    /**
     * body 参数加签 (相当于传递的 json 参数)
     *
     * @param obj 请求参数
     * @param timestamp
     * @return {@link String}
     */
    public static String bodySign(Object obj, Long timestamp) {
        String bodyStr = JSONObject.toJSONString(obj, SerializerFeature.MapSortField);
        Map<String, Object> params = new HashMap<>();
        params.put("timestamp", timestamp + "");
        params.put("body", bodyStr);
        String linkString = createLinkString(params, false);
        return XjSignMd5Util.md5(appKey + linkString + secretKey);
    }


    /**
     * query 参数加签 (相当于 url 后拼接的参数)
     *
     * @param params
     * @param timestamp
     * @return {@link String}
     */
    public static String querySign(Map<String, Object> params, Long timestamp) {
        params.put("timestamp", timestamp + "");
        String linkString = createLinkString(params, false);
        return XjSignMd5Util.md5(appKey + linkString + secretKey);
    }


    /**
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     *
     * @param params 需要排序并参与字符拼接的参数组
     * @param encode 是否需要UrlEncode
     * @return 拼接后字符串
     */
    private static String createLinkString(Map<String, Object> params, boolean encode) {
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key) + "";
            if (encode) {
                value = urlEncode(value, "UTF-8");
            }
            if (i == keys.size() - 1) {
                // 拼接时，不包括最后一个&字符
                sb.append(key).append("=").append(value);
            } else {
                sb.append(key).append("=").append(value).append("&");
            }
        }
        return sb.toString();
    }

    /**
     * URL转码
     *
     * @param content
     * @param charset
     * @return
     */
    private static String urlEncode(String content, String charset) {
        try {
            return URLEncoder.encode(content, charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("指定的编码集不对,您目前指定的编码集是:" + charset);
        }
    }
}
